package com.hsd.whb.wav;

import java.io.*;

public class StrToWav {


    private static int[] CODE_FREQUENCY = {1512, 1668, 1942, 2111, 2280, 2459, 2650, 2850, 3056, 3282, 3504, 3762, 4020, 4289, 4575, 4875};
    private static int sample_rate = 16000;

    private static int win_len = 1024;

    private static double[] hann = init_hann(win_len);

    public static double[] init_hann(int sample_len) {
        double[] value = new double[sample_len];
        for (int i = 0; i < sample_len; i++) {
            double h = 0.5 - 0.45 * Math.cos((2 * Math.PI * i) / (sample_len - 1));
            value[i] = h;
        }
        return value;
    }

    public static byte[] gen_sin_data(int frequency, double duration, int sampleRate) {
        int lenth = (int) (duration * sampleRate);
        byte[] value = new byte[lenth * 2];
        for (int i = 0; i < lenth; i++) {
            short v = (short) (32767 * Math.cos(2 * frequency * Math.PI * i / sampleRate) * hann[i]);
            byte[] bytes = shortToBytes(v);
            value[i * 2] = bytes[0];
            value[i * 2 + 1] = bytes[1];
        }
        return value;
    }

    public static byte[] shortToBytes(short num) {
        byte[] bytes = new byte[2];
        bytes[0] = (byte) (num & 0xFF);
        bytes[1] = (byte) ((num >> 8) & 0xFF);
        return bytes;
    }

    public static byte[] strToData(String string) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(500000);
        byte[] fill = new byte[512];
        byteArrayOutputStream.write(fill);
        for (int i = 0; i < string.length(); i++) {
            int ch = (int) string.charAt(i);
            int hi = ch / 16;
            int lo = ch % 16;
            byte[] data = gen_sin_data(CODE_FREQUENCY[hi], (float) (win_len) / sample_rate, sample_rate);
            byteArrayOutputStream.write(data);
            data = gen_sin_data(CODE_FREQUENCY[lo], (float) (win_len) / sample_rate, sample_rate);
            byteArrayOutputStream.write(data);
        }
        return byteArrayOutputStream.toByteArray();
    }


    public static File strToWav(String ssid, String pwd, String filePath) throws IOException {
        String content = ssid + "||" + pwd;
        CRC crc = new CRC();
        int crcResult = crc.crc(content);
        File file = new File(filePath + "/" + ssid + ".wav");
        if (!file.exists()) file.createNewFile();
        FileOutputStream outputStream = new FileOutputStream(file);
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
        WavFile wavFile = new WavFile(strToData(content + (char) crcResult + "\0"));
        wavFile.write(bufferedOutputStream);
        bufferedOutputStream.close();
        outputStream.close();
        return file;
    }

    public static ByteArrayOutputStream strToByteArrayOutputStream(String ssid, String pwd) throws IOException {
        String content = ssid + "||" + pwd;
        CRC crc = new CRC();
        int crcResult = crc.crc(content);
        WavFile wavFile = new WavFile(strToData(content + (char) crcResult + "\0"));
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(wavFile.getData().length + 44);
        wavFile.write(outputStream);
        return outputStream;
    }

}
